﻿using Dao.User;
using ShareCode.Entity.User;
using Infrastructure.Attributes.Ioc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Infrastructure.Model;
using Infrastructure.Util.Helper;
using Infrastructure.Util;
using Microsoft.Extensions.Configuration.UserSecrets;
using ShareCode.Dto.User;
using System.Configuration.Internal;
using Infrastructure.Model.User;
using ShareCode.Util.Helper;
using Infrastructure.MyException;
using ShareCode.Dto;
using ShareCode.KeyValue;

namespace Bll.User
{
    /// <summary>
    /// by zhouxin
    ///</summary>
    [Component]
    public class UserAccountBll : BaseContainDateBll<UserAccountEntity>
    {
        protected override UserAccountDao? Dao => (UserAccountDao?)base.Dao;

        [Autowired]
        public UserAccountDao SetDao { set { this._Dao = value; } }
        [Autowired]
        public UserEntryInformationDao? InformationDao { get; set; }
        [Autowired]
        public UserOrgDao? OrgDao { get; set; }

        public Task<bool> VerificationUserName(string userName) {
            return Dao!.IsAnyAsync(t => t.UserName == userName);
        }


        public async Task<List<UserAccountEntity>> GetUserByNameOrMobileAsync(string userName, string MobileNumber)
        {
            var model = await Dao!.GetListAsync(t => t.UserName == userName || t.Mobile == MobileNumber);

            return model;
        }

        public async Task<UserSessionInfoModel?> LoginByToken(string token)
        {
            var currenttime = DateTimeHelper.ConvertDateTime2Int(DateTime.Now);

            var userToken = await Dao!.FirstAsync(t => t.Token == token && t.TokenExpire > currenttime);

            if (userToken == default) return default;

            var lifeTime = ConfigurationManagerModel.ThreadSafeReadInt("TokenLifeTime");

            TimeSpan ts = new TimeSpan(0, lifeTime, 0);

            UserEntryInformationEntity? emodel = null;
            UserOrgEntity? orgmodel = null;

            emodel = await InformationDao!.FirstAsync(t => t.AccountId == userToken.Id, t => t.LastLoginTime, SqlSugar.OrderByType.Desc);

            if (emodel != null)
            {
                orgmodel = await OrgDao!.GetByIdAsync(emodel.OrgId);
            }

            var UsersToken = new UserSessionInfoModel(userToken, emodel, orgmodel);

             RedisHelper.GetObject(RedisDbBusiness.Core)?.StringSet(token, UsersToken, ts);

            return UsersToken;
        }

        public async Task<LoginReturnDto> LoginByNameAndPswAsync(LoginByNameAndPswResqestDto loginByNameAndPsw)
        {

            var model = await Dao!.GetFirstAsync(t => t.UserName == loginByNameAndPsw.UserName);

            if (model == null)
            {
                throw new ShowUserLogicException("登录失败").AddSonMessage(nameof(loginByNameAndPsw.UserName), "没有找到此用户");
            }

            var strResult = HashHelper.GetPsw(loginByNameAndPsw.Password!, model.Salt!);

            if (strResult != model.Psw)
            {
                throw new ShowUserLogicException("登录失败").AddSonMessage(nameof(loginByNameAndPsw.Password), "密码不正确");
            }

            UserEntryInformationEntity? emodel = null;
            UserOrgEntity? orgmodel = null;

            emodel = await InformationDao!.FirstAsync(t => t.AccountId == model.Id, t => t.LastLoginTime, SqlSugar.OrderByType.Desc);

            if (emodel != null)
            {
                orgmodel = await OrgDao!.GetByIdAsync(emodel.OrgId);
            }

            //更新token
            var token = SnowflakeIDcreator.NextId().ToString();

            if (loginByNameAndPsw.SaveLoginState > 0)
            {
                model.Token = token;
                var lifeTime1 = ConfigurationManagerModel.ThreadSafeReadInt("TokenLifeTime");
                model.TokenExpire = DateTimeHelper.ConvertDateTime2Int(DateTime.Now.AddDays(lifeTime1));
            }

            //更新最后登录时间，

            model.LastLoginTime = DateTimeHelper.GetTimeStamp();
            await Dao.UpdateAsync(model);

            if (emodel != default)
            {
                emodel.LastLoginTime = DateTimeHelper.GetTimeStamp();
                await InformationDao.UpdateAsync(emodel);
            }

            var uim = new UserSessionInfoModel(model, emodel, orgmodel);

            var lifeTime = ConfigurationManagerModel.ThreadSafeReadInt("SessionLifeTime");
            TimeSpan ts = new(0, lifeTime, 0);
            RedisHelper.GetObject(RedisDbBusiness.Core)?.StringSet<UserSessionInfoModel>(RedisKeyPrefix.Token + token, uim, ts);


            return new LoginReturnDto(model, emodel, orgmodel);
        }

        public async Task<long> Register(UserRegisterDto registerDto)
        {

            var model = await Dao!.IsAnyAsync(t => t.UserName == registerDto.UserName);
            if (model)
            {
                throw new ShowUserLogicException("用户名已存在").AddSonMessage(nameof(registerDto.UserName), "用户名已存在");
            }

            var entity = (UserAccountEntity)registerDto;
            entity.Salt = SnowflakeIDcreator.NextId().ToString();
            entity.Psw = HashHelper.GetPsw(entity.Psw!, entity.Salt);


            try
            {
                await Dao.InsertAsync(entity);
            }
            catch (Exception ex)
            {
                throw new ShowUserLogicException(ex.Message);
            }

            return entity.Id;
        }

        public async Task<long> Register2(FileUploadDto<UserRegisterDto> registerDto)
        {
            var AvatarPath = UploadFileHelper.SaveFormFile(registerDto.Files!, EnumFileUsage.UserAvatar);

            registerDto.Model!.Avatar = AvatarPath;

            var id = await Register(registerDto.Model);

            //if (id.HasErr) return id;

            return id;
        }
    }
}
